/**
 *
 */

package com.moogene.saad.gameplay.stages;

import java.util.ArrayList;
import java.util.HashMap;

import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;

import com.moogene.android.InfoMediator;
import com.moogene.android.R;
import com.moogene.android.engine.mmi.Book;
import com.moogene.android.engine.mmi.ImageLayer;
import com.moogene.android.engine.mmi.Layer;
import com.moogene.android.engine.mmi.Page;
import com.moogene.saad.gameplay.attacter.Attacker;
import com.moogene.saad.gameplay.data.IDataHandler;
import com.moogene.saad.gameplay.defender.Tower;
import com.moogene.saad.gameplay.defender.TowerTemplate;

/**
 * @author 28849218
 */
public class BattleField extends Page implements IDataHandler{

	private static final int ATTACKERS_ENTER_GAP = 20;

	private ArrayList<Tower> towers;
	
	private HashMap<String, TowerTemplate> towerTemplates;
	
	private int[][] routes;
	
	private ArrayList<Attacker> initAttackers;

    private ArrayList<Attacker> attackers = new ArrayList<Attacker>();
	
	private Bitmap bg;
	
	private Bitmap bgGirds;
	
	private Occupyable[][] girdsOccupied;
	
	private ImageLayer shadowTower;
	
	private boolean shouldfollowCameraWhenDrag = false;
	
	private int curEnteringAttacker = -1;

    //TODO: imgBg created in the constructor
	private void init(Bitmap imgBg, HashMap<String, TowerTemplate> towerTemplates, ArrayList<Tower> towers, int[][] routes) {
		this.towers = towers;
		this.routes = routes;
		this.towerTemplates = towerTemplates;
		this.bg = imgBg;
		setBgImg(imgBg);
		setupBgGirds();
		for(Tower t: towers){
    		super.addLayer(t);
    	}
	}

	public static BattleField load(String name){
		BattleField bf = null;
		if(name.equalsIgnoreCase("level1")){
			Bitmap imgBg = InfoMediator.getBitmap(R.drawable.bg1);
			ArrayList<Tower> towers = new ArrayList<Tower>();
			HashMap<String, TowerTemplate> towerTemplates = TowerTemplate.load(name);
			Tower t = towerTemplates.get("mouse1").copy();
//			t.setAlign(2, 2);
			t.setFixed(true);
			towers.add(t);
			int[][] routes = new int[][]{{0, 172},{1374, 172}};
			bf = new BattleField();
			bf.init(imgBg, towerTemplates, towers, routes);
			bf.setOccupy(t, 2, 2);
		}
		return bf;
	}
	
	protected boolean canDrag(){
		return true;
	}
	
	@Override
	protected boolean shouldFollowCameraWhenDrag(){
		return shouldfollowCameraWhenDrag;
	}
	
	void setFollowCameraWhenDrag(boolean shouldCheck){
		shouldfollowCameraWhenDrag = shouldCheck;
	}

    /**
     *
     */
    public void addAttackers(ArrayList<Attacker> attackers) {
    	this.initAttackers = attackers;
    	this.attackers.clear();
    	curEnteringAttacker = 0;
//    	for(Attacker att: attackers){
//    		addLayer(att);
//    		att.enter();
//    	}
    }
    
//    public void addAttacker(Attacker attacker){
//    	attackers.add(attacker);
//    	addLayer(attacker);
//    	attacker.enter();
//    }
    
    public ArrayList<Attacker> getAttackers(){
    	return attackers;
    }

	private void setupBgGirds() {
		bgGirds = Bitmap.createBitmap(bg.getWidth(), bg.getHeight(), Bitmap.Config.RGB_565);
		Canvas c = new Canvas(bgGirds);
		c.drawBitmap(bg, 0, 0, null);
		Bitmap girdBg= InfoMediator.getBitmap(R.drawable.girdbg);
		/*Gird size is 128X128 */
		int xOff = (128 - girdBg.getWidth()) >> 1;
		int yOff = (128 - girdBg.getHeight()) >> 1;
		int row = (bg.getHeight() >> 7) + 1;
		int col = (bg.getWidth() >> 7) + 1;
		girdsOccupied = new Occupyable[row][col];
		for(int i = 0; i < row; i++){
			for(int j = 0; j < col; j++){
				c.drawBitmap(girdBg, (j << 7) + xOff, (i << 7) + yOff, null);
			}
		}
	}
    
    public ArrayList<Tower> getTowers() {
		return towers;
	}

	@Override
    public void addLayer(Layer layer){
		super.addLayer(layer);
    	if(layer instanceof Tower){
    		Tower t = (Tower)layer;
        	if(!towers.contains(t)){
        		towers.add(t);
        	}
    	}
    }
	
	@Override
	public void removeLayer(Layer layer) {
		super.removeLayer(layer);
		if(layer instanceof Tower){
			towers.remove(layer);
		}
		if(layer instanceof Attacker){
			attackers.remove(layer);
		}
	}
    
    public HashMap<String, TowerTemplate> getTowerTemplates() {
		return towerTemplates;
	}

	/* (non-Javadoc)
     * @see com.moogene.android.engine.mmi.Page#start()
     */
    @Override
    public void onStart() {

    }

    @Override
    public void update() {
        super.update();
        if(attackers == null){
        	return;
        }
        if(curEnteringAttacker != -1){
        	if(Book.getInstance().getCurPageCounter() % ATTACKERS_ENTER_GAP == 0){
        		Attacker att = initAttackers.get(curEnteringAttacker);
        		addLayer(att);
        		attackers.add(att);
//        		att.enter();
        		curEnteringAttacker ++;
        		if(curEnteringAttacker >= initAttackers.size()){
        			curEnteringAttacker = -1;
        		}
        	}
        }
        for(Tower t: towers){
        	if(t.getTarget() != null){
        		continue;
        	}
            for(Attacker a: attackers){
                t.scanEnemy(a);
            }
        }
    }
    
	public void onLayerDragStart(Layer dragLayer){
		if(dragLayer instanceof Tower){
			Tower t = (Tower)dragLayer;
			setBgImg(bgGirds);
			shadowTower = new ImageLayer(t.getPreview());
			Paint p = new Paint();
			p.setAlpha(0x60);
			shadowTower.setPaint(p);
			shadowTower.setAnchor(t.getAnimlite().getAnchor().getAnchorX(), t.getAnimlite().getAnchor().getAnchorY());
			updateShaowTowerPos(t);
			int col = t.getX() >> 7;
			int row = t.getY() >> 7;
			if(girdsOccupied[row][col] == t){
				girdsOccupied[row][col] = null;
			}
			addLayer(shadowTower);
		}
	}
	
	public void onLayerDragged(Layer dragLayer){
		if(dragLayer instanceof Tower){
			Tower t = (Tower)dragLayer;
			if(!updateShaowTowerPos(t)){
				shadowTower.hide();
				t.setCanOccupyThis(false);
			}else{
				shadowTower.unHide();
				t.setCanOccupyThis(true);
			}
		}
	}
	
	private boolean updateShaowTowerPos(Tower dragTower){
		int col = dragTower.getX() >> 7;
		int row = dragTower.getY() >> 7;
		int x = (col << 7) + 64;
		int y = (row << 7) + 64;
		shadowTower.setLocation(x, y);
		if(girdsOccupied[row][col] != null){
			return false;
		}else{
			return true;
		}
	}

	public void onLayerDragEnd(Layer dragLayer) {
		if (dragLayer instanceof Tower) {
			Tower t = (Tower) dragLayer;
			setBgImg(bg);
			int col = shadowTower.getX() >> 7;
			int row = shadowTower.getY() >> 7;
			if (girdsOccupied[row][col] != null) {
				removeLayer(t);
			} else {
				setOccupy(t, row, col);
			}
			removeLayer(shadowTower);
		}
	}
	
	private void setOccupy(Occupyable o, int row, int col){
		girdsOccupied[row][col] = o;
		o.setAlign(row, col);
	}

	@Override
	public void checkVersion() {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void save() {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void upload() {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void download() {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void onInit(String... args) {
		String name = args[0];
		if(name.equalsIgnoreCase("level1")){
			Bitmap imgBg = InfoMediator.getBitmap(R.drawable.bg1);
			ArrayList<Tower> towers = new ArrayList<Tower>();
			HashMap<String, TowerTemplate> towerTemplates = TowerTemplate.load(name);
			Tower t = towerTemplates.get("mouse1").copy();
//			t.setAlign(2, 2);
			t.setFixed(true);
			towers.add(t);
			int[][] routes = new int[][]{{0, 172},{1374, 172}};
			init(imgBg, towerTemplates, towers, routes);
			setOccupy(t, 2, 2);
		}
		
	}

}
